package com.pi.smart.base.task.processor;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.pi.base.enumerate.redis.RedisCacheEnum;
import com.pi.base.util.cache.RedisUtil;
import com.pi.base.util.lang.ByteUtil;
import com.pi.comm.sequence.SnowflakeFactory;
import com.pi.dc.model.DcLogPostForm;
import com.pi.dc.service.SmartLogService;
import com.pi.smart.client.ins.bed.category.BedInsEnum;
import com.pi.smart.client.ins.bed.domain.SmartBedCmd;
import com.pi.smart.client.ins.comm.annotation.ForLogIns;
import com.pi.smart.client.ins.comm.category.SmartInsEnum;
import com.pi.smart.client.ins.comm.domain.BaseInsMessage;
import com.pi.smart.client.ins.comm.variety.LogInsHandler;

/**
 * @description 小棉被的日志处理机
 * @author chenmf
 * @date 2019年05月02日22:54:51
 */
@ForLogIns(ins = SmartInsEnum.SMART_BED)
@Component
public class SmarInsLogHandler implements LogInsHandler{

  private static final Logger logger = LoggerFactory.getLogger(SmarInsLogHandler.class);
  
  private static final Long OEM_SOURCE = 2540069822922752L;
  
  @Autowired
  private SmartLogService smartLogService;
  
  @Override
  public void handle(BaseInsMessage cmdLog) {
    if(null == cmdLog) {
      logger.debug("指令数据为空：", cmdLog);
      return;
    }
    try{
      handleMessage(cmdLog);
    }catch(Exception e) {
      logger.error("处理小棉被指令失败：", e);
    }
  }
  
  private void handleMessage(BaseInsMessage cmdLog) throws IOException {

    if(null == cmdLog.getCmd()){
      logger.error("消息数据为空: {}", cmdLog);
      return;
    }
    BedInsEnum bedInsEnum;
    if((cmdLog.getCmd()[0] & 0xFF)  == 0xFE && ((cmdLog.getCmd()[1] & 0xFF) == 0x01 || (cmdLog.getCmd()[1] & 0xFF) == 0x09)){
      bedInsEnum = handleNewSmartbed(cmdLog);
    }else {
      bedInsEnum = handleOldSmartbed(cmdLog);
    }
    saveAndDistributeInsLog(cmdLog,bedInsEnum);
  }
  
  private BedInsEnum handleNewSmartbed(BaseInsMessage cmdLog) throws IOException {
    byte cmd = cmdLog.getCmd()[2];//FE 01 01 08 00 01 10 20 30 40 50 60 70 80 11 22
    byte[] devCode = new byte[8];
    System.arraycopy(cmdLog.getCmd(), 5, devCode, 0, 8);
    String deviceCode = ByteUtil.byteToHex(devCode,false);
    BedInsEnum bedInsEnum;
    if((cmd & 0xFF) == 0x01){
      logger.info("WIFI配网： {}", deviceCode);
      bedInsEnum = BedInsEnum.SYSTEM_INI;
    }else if((cmd & 0xFF) == 0xF6){
      //FE 09 F6 09 00 01 10 20 30 40 50 60 01 11 22
      int success = cmdLog.getCmd()[13] & 0xFF;
      logger.info("是否配置成功  " + success);
      bedInsEnum = BedInsEnum.WIFI_CONFIRM;
    }else if((cmd & 0xFF) == 0x02){
      bedInsEnum = BedInsEnum.SLEEP_STATUS;
      logger.info("接收上报成功： {}", deviceCode);
    }else {
      bedInsEnum = null;
    }
    return bedInsEnum;
  }
  
  private BedInsEnum handleOldSmartbed(BaseInsMessage cmdLog) throws IOException {
    String deviceCode = null;
    byte[] devCode = new byte[8];
    int byteBodyLength = cmdLog.getCmd().length > 9 ? cmdLog.getCmd()[9] & 0xFF : 0;
    BedInsEnum bedInsEnum;
    switch(byteBodyLength) {
      case 3:
        System.arraycopy(cmdLog.getCmd(), 1, devCode, 0, 8);
        deviceCode = ByteUtil.byteToHex(devCode, false);
        logger.info("接收到开机数据, 设备编号:{}, 数据长度: {}, 温度:{}, 湿度:{}, 电压: {}",
            deviceCode, cmdLog.getCmd()[9], cmdLog.getCmd()[10], cmdLog.getCmd()[11], cmdLog.getCmd()[12]);
        bedInsEnum = BedInsEnum.SLEEP_STATUS;
        break;
      case 1:
        System.arraycopy(cmdLog.getCmd(), 1, devCode, 0, 8);
        deviceCode = ByteUtil.byteToHex(devCode, false);
        logger.info("接收到WIFI 设置数据, 设备编号:{}, 数据长度: {}, 是否设置成功：{}",
            ByteUtil.byteToHex(devCode), cmdLog.getCmd()[9], cmdLog.getCmd()[10]);
        bedInsEnum = BedInsEnum.WIFI_CONFIRM;
        break;
      default:
        logger.error("未知类型的数据: {}", ByteUtil.byteToHex(devCode));
        bedInsEnum = null;
        break;
    }
    if(StringUtils.isNotBlank(deviceCode) && !deviceCode.equalsIgnoreCase(cmdLog.getDevCode())) {
      logger.error("接收到的指令设备id和实际不符: {}", cmdLog.toString());
    }
    return bedInsEnum;
  }
  
  private void saveAndDistributeInsLog(BaseInsMessage cmdLog, BedInsEnum bedInsEnum) throws IOException {
    if(null != bedInsEnum){
      SmartBedCmd cmd = new SmartBedCmd();
      cmd.setCmd(cmdLog.getCmd());
      cmd.setMessageId(SnowflakeFactory.getDefaultWorker().nextId());
      cmd.setTs(System.currentTimeMillis());
      cmd.setDevCode(cmdLog.getDevCode());
      cmd.setInsEnum(bedInsEnum);
      RedisUtil.rpush(RedisCacheEnum.SMART_BED_CMD_COMMON, cmd);
    }
    DcLogPostForm form = new DcLogPostForm();
    form.setCmdId(cmdLog.getMessageId());
    form.setDevCode(cmdLog.getDevCode());
    form.setRawData(ByteUtil.byteToHex(cmdLog.getCmd()));
    form.setSourceId(OEM_SOURCE);
    smartLogService.addSmartLog(form);
  }

}
